package com.commerceE.managedBean;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.UploadedFile;

import com.commerceE.common.exception.ServiceException;
import com.commerceE.dao.ProductOptionValueDao;
import com.commerceE.domain.Category;
import com.commerceE.domain.Images;
import com.commerceE.domain.Product_instance;
import com.commerceE.domain.Product_option_values;
import com.commerceE.domain.Products;
import com.commerceE.service.CategoryService;
import com.commerceE.service.ImageService;
import com.commerceE.service.ProductInstanceService;
import com.commerceE.service.ProductService;
import com.commerceE.util.Constant;
import com.commerceE.util.SpringUtil;

@ManagedBean(name = "productBean")
@RequestScoped
public class ProductBean {

	@ManagedProperty(value = "#{adminHomeBean}")
	private AdminHomeBean adminHomeBean;

	private List<Products> productList = null;

	private Products selectedProduct = null;
	
	private Products newProduct = new Products();

	private boolean skip;

	private Long categoryId;

	private Category selectedCategory;

	private List<Category> categoryList;

	@ManagedProperty(value = "#{productService}")
	private ProductService productService;
	
	private ProductInstanceService productInstanceService;

	private CategoryService categoryService;
	
	private ImageService imageService;
	
	private ProductOptionValueDao productOptionValueDao;

	private List<Images> loadedImages;
	
	private List<Product_instance> productInstanceList;

	private Images selectedImage;
	
	private Product_instance selectedProductInstance;
	
	private Images editedImage = new Images();

	private StreamedContent listImage = null;

	private Long image_selectedProductId = null;
	
	private Long productInstance_selectedProductId = null;
	
	private Product_instance new_product_instance = null;
	
	private List<String> imageTypeList = Constant.getImagesTypeList();
	
	ExternalContext externalContext = FacesContext.getCurrentInstance()
			.getExternalContext();
	Map<String, Object> sessionMap = externalContext.getSessionMap();
	
	private List<Product_option_values>  colorList;
	
	private List<Product_option_values>  sizeList;
    
    private Product_option_values size_product_option_value;

    private String importOrExport;
    
	public ProductBean() {
		productService = (ProductService) SpringUtil
				.getBeanById("productService");
		categoryService = (CategoryService) SpringUtil
				.getBeanById("categoryService");
		imageService = (ImageService) SpringUtil.getBeanById("imageService");
		productInstanceService = (ProductInstanceService) SpringUtil.getBeanById("productInstanceService");
		productOptionValueDao = (ProductOptionValueDao)SpringUtil.getBeanById("productOptionValueDao");
		
		sizeList = productOptionValueDao.getProductOptionValueListByOptionId(2L);
		colorList = productOptionValueDao.getProductOptionValueListByOptionId(1L);

		loadedImages = (List<Images>)sessionMap.get("loadedImages");
		productInstanceList = (List<Product_instance>)sessionMap.get("productInstanceList");
		new_product_instance = new Product_instance();
		try {
			productList = productService.getAllListOfProduct();
			categoryList = categoryService.getAllListOfCategory();
		} catch (ServiceException e) {
			e.printStackTrace();
		}
	}

	public void onDelete() {
		if (selectedProduct == null) {
			FacesMessage msg = new FacesMessage("Please select 1 row first!",
					"");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		} else {
			try {
				productService.deleteProduct(selectedProduct.getProductId());
				productList.remove(selectedProduct);
				selectedProduct = null;
			} catch (ServiceException e) {
				e.printStackTrace();
			}
			productList.remove(selectedProduct);
		}

	}

	public String addProductInput() {
		adminHomeBean.setCenterPage("/xhtml/productInput.xhtml");
		return null;
	}

	public String editProductInput() {
		if (selectedProduct == null) {
			FacesMessage msg = new FacesMessage("Please select 1 row first!",
					"");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		} else {
			newProduct = selectedProduct;
			adminHomeBean.setCenterPage("/xhtml/productInput.xhtml");
		}
		return null;
	}

	public String addProductSubmit() {
		try {
			if (newProduct.getProductId() != null
					&& newProduct.getProductId() != 0) {
				productService.updateProduct(newProduct);
				productList = productService.getAllListOfProduct();
			} else {
				productService.insertProduct(newProduct);
				productList.add(newProduct);
			}
		} catch (ServiceException e) {
			e.printStackTrace();
		}
		newProduct = new Products();
		selectedProduct = null;
		adminHomeBean.setCenterPage("/xhtml/productList.xhtml");

		return null;
	}
	
	public void addImageInput() {
		if (selectedProduct == null) {
			FacesMessage msg = new FacesMessage("Please select 1 row first!",
					"");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		} else {
			image_selectedProductId = selectedProduct.getProductId();
			sessionMap.put("image_selectedProductId", image_selectedProductId);
			loadedImages = imageService.getImagesByInstanceId(image_selectedProductId);
			sessionMap.put("loadedImages", loadedImages);
			adminHomeBean.setCenterPage("/xhtml/productImages.xhtml");
		}
	}

	public void saveUploadedImages() {
		if (loadedImages != null) {
			String filenames = "";
			for (Images file : loadedImages) {
				filenames = filenames + ", " + file.getPath();
			}
			FacesMessage msg = new FacesMessage("Succesful", filenames
					+ "  is saved.");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}
	}

	public void handleFileUpload(FileUploadEvent event) {
		UploadedFile file = event.getFile();
		image_selectedProductId = (Long) sessionMap
				.get("image_selectedProductId");
		String imageName = image_selectedProductId + "_" + file.getFileName();
		try {
			FileOutputStream fileOutputStream = new FileOutputStream(
					externalContext.getRealPath("//image_upload") + "//"
							+ imageName, true);

			byte[] buffer = new byte[1024];
			int bulk;
			InputStream inputStream = file.getInputstream();
			while (true) {
				bulk = inputStream.read(buffer);
				if (bulk < 0) {
					break;
				}
				fileOutputStream.write(buffer, 0, bulk);
				fileOutputStream.flush();
			}

			fileOutputStream.close();
			inputStream.close();

			FacesMessage msg = new FacesMessage("Successful",
					file.getFileName() + " is uploaded.");
			FacesContext.getCurrentInstance().addMessage(null, msg);

		} catch (IOException e) {
			e.printStackTrace();
			FacesMessage error = new FacesMessage(
					"The files were not uploaded!");
			FacesContext.getCurrentInstance().addMessage(null, error);
		}
		Images image = new Images();
		image.setPath(imageName);
		image.setDefaultFlag(false);
		image.setDisplayOrder(10);
		image.setInstanceId(image_selectedProductId);
		try {
			imageService.insertImage(image);
		} catch (ServiceException e) {
			e.printStackTrace();
		}
		loadedImages = imageService.getImagesByInstanceId(image_selectedProductId);
		sessionMap.put("loadedImages",loadedImages);
	}

	public void onEditImageInput() {
		if(selectedImage==null){
			FacesMessage msg = new FacesMessage("Please select image . ", "");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		} else{
			editedImage = new Images();
			editedImage.setImageId(selectedImage.getImageId());
			editedImage.setInstanceId(selectedImage.getInstanceId());
			editedImage.setDefaultFlag(selectedImage.getDefaultFlag());
			editedImage.setDisplayOrder(selectedImage.getDisplayOrder());
			editedImage.setPath(selectedImage.getPath());
			editedImage.setType(selectedImage.getType());
		}
	}
	
	public void onEditImageSubmit() {
		try {
			imageService.updateImage(editedImage);
			image_selectedProductId = (Long)sessionMap.get("image_selectedProductId");
			loadedImages = imageService.getImagesByInstanceId(image_selectedProductId);
			sessionMap.put("loadedImages", loadedImages);
		} catch (ServiceException e) {
			e.printStackTrace();
		}
	}
	

	public void onImageDelete() {
		if (selectedImage == null) {
			FacesMessage msg = new FacesMessage("Please select image . ", "");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		} else {
			try {
				imageService.deleteImage(selectedImage.getImageId());
				loadedImages = (List<Images>) sessionMap.get("loadedImages");
				loadedImages.remove(selectedImage);
			} catch (ServiceException e) {
				e.printStackTrace();
			}
		}
	}

	
	public void addProductInstance() {
		if (selectedProduct == null) { 
			FacesMessage msg = new FacesMessage("Please select 1 row first!",
					"");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		} else {
			productInstance_selectedProductId = selectedProduct.getProductId();
			sessionMap.put("productInstance_selectedProductId", productInstance_selectedProductId);
			productInstanceList = productInstanceService.getProductInstanceByProductId(productInstance_selectedProductId);
			sessionMap.put("productInstanceList", productInstanceList);
			adminHomeBean.setCenterPage("/xhtml/productInstanceList.xhtml");
		}
	}
	
	public void onAddProductInstanceInput(){
		new_product_instance = new Product_instance();
		importOrExport="import";
		productInstance_selectedProductId = (Long)sessionMap.get("productInstance_selectedProductId");
		new_product_instance.setProductId(productInstance_selectedProductId);
	}
	
	public void onProductInstanceDelete(){
		
//		if (new_product_instance == null) { 
//			FacesMessage msg = new FacesMessage("Please select 1 row first!",
//					"");
//			FacesContext.getCurrentInstance().addMessage(null, msg);
//		}
	}
	
	public void onEditProductInstanceInput(){
		new_product_instance = new Product_instance();
		importOrExport="export";
		productInstance_selectedProductId = (Long)sessionMap.get("productInstance_selectedProductId");
		new_product_instance.setProductId(productInstance_selectedProductId);
	}
	
	public void submitProductInstanceButton(){
		productInstance_selectedProductId = (Long)sessionMap.get("productInstance_selectedProductId");
		if(new_product_instance.getColorId()==null || new_product_instance.getSizeId()==null){
			FacesMessage msg = new FacesMessage("Please select the size and color!",
					"");
			FacesContext.getCurrentInstance().addMessage(null, msg);
			return;
		}
		Product_instance pi = productInstanceService.getProductInstanceByProductIdAndColorAndSize(productInstance_selectedProductId, 
								new_product_instance.getColorId(), new_product_instance.getSizeId());
		if(pi==null){
			productInstanceService.insertProductInstance(new_product_instance);
		}else{
			if("import".equals(importOrExport)){
				pi.setQuantity(pi.getQuantity()+new_product_instance.getQuantity());
			}else if("export".equals(importOrExport)){
				int new_quantity = pi.getQuantity()-new_product_instance.getQuantity();
				if(new_quantity<0){
					FacesMessage msg = new FacesMessage("The current total quantity is less than "+new_product_instance.getQuantity(),
							"");
					FacesContext.getCurrentInstance().addMessage(null, msg);
					return;
				}
				pi.setQuantity(pi.getQuantity()-new_product_instance.getQuantity());
			}
			productInstanceService.updateProductInstance(pi);
		}
		productInstanceList = productInstanceService.getProductInstanceByProductId(productInstance_selectedProductId);
		sessionMap.put("productInstanceList", productInstanceList);
	}
	
	//setter and getter
	public List<Products> getProductList() {
		return productList;
	}

	public void setProductList(List<Products> productList) {
		this.productList = productList;
	}

	public ProductService getProductService() {
		return productService;
	}

	public void setProductService(ProductService productService) {
		this.productService = productService;
	}

	public Products getSelectedProduct() {
		return selectedProduct;
	}

	public void setSelectedProduct(Products selectedProduct) {
		this.selectedProduct = selectedProduct;
	}

	public Products getNewProduct() {
		return newProduct;
	}

	public void setNewProduct(Products newProduct) {
		this.newProduct = newProduct;
	}

	public boolean isSkip() {
		return skip;
	}

	public void setSkip(boolean skip) {
		this.skip = skip;
	}

	public Long getCategoryId() {
		return categoryId;
	}

	public void setCategoryId(Long categoryId) {
		this.categoryId = categoryId;
	}

	public AdminHomeBean getAdminHomeBean() {
		return adminHomeBean;
	}

	public void setAdminHomeBean(AdminHomeBean adminHomeBean) {
		this.adminHomeBean = adminHomeBean;
	}

	public Category getSelectedCategory() {
		return selectedCategory;
	}

	public void setSelectedCategory(Category selectedCategory) {
		this.selectedCategory = selectedCategory;
	}

	public List<Category> getCategoryList() {
		return categoryList;
	}

	public void setCategoryList(List<Category> categoryList) {
		this.categoryList = categoryList;
	}

	public CategoryService getCategoryService() {
		return categoryService;
	}

	public void setCategoryService(CategoryService categoryService) {
		this.categoryService = categoryService;
	}

	public ImageService getImageService() {
		return imageService;
	}

	public void setImageService(ImageService imageService) {
		this.imageService = imageService;
	}

	public List<Images> getLoadedImages() {
		return loadedImages;
	}

	public void setLoadedImages(List<Images> loadedImages) {
		this.loadedImages = loadedImages;
	}

	public Images getSelectedImage() {
		return selectedImage;
	}

	 
	public List<String> getImageTypeList() {
		return imageTypeList;
	}

	public void setImageTypeList(List<String> imageTypeList) {
		this.imageTypeList = imageTypeList;
	}

	public void setSelectedImage(Images selectedImage) {
		this.selectedImage = selectedImage;
	}

	public Images getEditedImage() {
		return editedImage;
	}

	public void setEditedImage(Images editedImage) {
		this.editedImage = editedImage;
	}

	public StreamedContent getListImage() {
		return listImage;
	}

	public void setListImage(StreamedContent listImage) {
		this.listImage = listImage;
	}

	public Long getImage_selectedProductId() {
		return image_selectedProductId;
	}

	public void setImage_selectedProductId(Long image_selectedProductId) {
		this.image_selectedProductId = image_selectedProductId;
	}

	public ProductInstanceService getProductInstanceService() {
		return productInstanceService;
	}

	public void setProductInstanceService(
			ProductInstanceService productInstanceService) {
		this.productInstanceService = productInstanceService;
	}

	public List<Product_instance> getProductInstanceList() {
		return productInstanceList;
	}

	public void setProductInstanceList(List<Product_instance> productInstanceList) {
		this.productInstanceList = productInstanceList;
	}

	public Product_instance getSelectedProductInstance() {
		return selectedProductInstance;
	}

	public void setSelectedProductInstance(Product_instance selectedProductInstance) {
		this.selectedProductInstance = selectedProductInstance;
	}

	public Long getProductInstance_selectedProductId() {
		return productInstance_selectedProductId;
	}

	public void setProductInstance_selectedProductId(
			Long productInstance_selectedProductId) {
		this.productInstance_selectedProductId = productInstance_selectedProductId;
	}

	public ProductOptionValueDao getProductOptionValueDao() {
		return productOptionValueDao;
	}

	public void setProductOptionValueDao(ProductOptionValueDao productOptionValueDao) {
		this.productOptionValueDao = productOptionValueDao;
	}

	public Product_instance getNew_product_instance() {
		return new_product_instance;
	}

	public void setNew_product_instance(Product_instance new_product_instance) {
		this.new_product_instance = new_product_instance;
	}

	public List<Product_option_values> getColorList() {
		return colorList;
	}

	public void setColorList(List<Product_option_values> colorList) {
		this.colorList = colorList;
	}

	public List<Product_option_values> getSizeList() {
		return sizeList;
	}

	public void setSizeList(List<Product_option_values> sizeList) {
		this.sizeList = sizeList;
	}

	public Product_option_values getSize_product_option_value() {
		return size_product_option_value;
	}

	public void setSize_product_option_value(
			Product_option_values size_product_option_value) {
		this.size_product_option_value = size_product_option_value;
	}

	public String getImportOrExport() {
		return importOrExport;
	}

	public void setImportOrExport(String importOrExport) {
		this.importOrExport = importOrExport;
	}
	

}
